package work.linruchang.mybatisplussamplestest.dao;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.toolkit.AopUtils;

import java.io.Serializable;
import java.lang.reflect.Type;

public interface MyBaseMapper<T> extends BaseMapper<T> {

    /**
     * 物理删除
     * @param id
     * @return
     */
    int deleteByIdPhysical(Serializable id);

    /**
     * 物理删除
     * @param entity
     * @return
     */
    int deleteByIdPhysical(T entity);

    /**
     * 逻辑删除
     *
     * 打算调这个方法，如果发现实体没有@TableLogic就会报异常出来提示用户
     * @param id
     * @return
     */
    int deleteByIdLogic(Serializable id);

    /**
     * 逻辑删除
     * @param entity
     * @return
     */
    int deleteByIdLogic(T entity);

    /**
     * 删除
     * @param id 主键ID
     * @param logicDeleteFlag null老逻辑  true逻辑删除 false物理删除
     * @return
     */
    default int deleteById(Serializable id, Boolean logicDeleteFlag) {

        //无指定则根据实体是否有@TableLogic进行评判（原逻辑）
        if(logicDeleteFlag == null) {return deleteById(id);}

        //指定逻辑删除、物理删除
        if(BooleanUtil.isTrue(logicDeleteFlag)) {
            Class currentMapperClazz = (Class) ReflectUtil.getFieldValue(ReflectUtil.getFieldValue(AopUtils.getTargetObject(this),"h"),"mapperInterface");
            Type typeArgument = TypeUtil.getTypeArgument(currentMapperClazz, 0);
            TableInfo tableInfo = TableInfoHelper.getTableInfo((Class<?>) typeArgument);
            if(tableInfo.isWithLogicDelete()) {
                return deleteByIdLogic(id);
            }
            throw new RuntimeException(StrUtil.format("当前表【{}】：不支持逻辑删除，请检查是否有配置逻辑删除字段", tableInfo.getTableName()));
        }else {
            return deleteByIdPhysical(id);
        }
    }

}
